﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;

namespace Miris.HumanMilkAnalyser.WPF.Converter
{
    /// <summary>
    /// Converter that returns value for range ruler.
    /// </summary>
    public class TestResultChartRangeRulerValueConverter : IMultiValueConverter
    {
        /// <summary>
        /// Converter that returns value for range ruler.
        /// </summary>
        /// <param name="values">
        /// 0, MaxValue. 
        /// 1, CurrentIndex. 
        /// </param>
        /// <param name="targetType"></param>
        /// <param name="parameter"></param>
        /// <param name="culture"></param>
        /// <returns>Ruler Indicator</returns>
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var maxValue = ColumnChartHeper.ConvertToInt32(values[0]);
            var currentIndex = ColumnChartHeper.ConvertToInt32(values[1]);

            if (maxValue > 0 && currentIndex > 0)
            {
                var result = maxValue / 5 * currentIndex;

                return result.ToString();
            }
            else
            {
                return null;
            }
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    /// <summary>
    /// Converter that returns Width for Item.
    /// </summary>
    public class TestResultChartItemWidthConverter : IMultiValueConverter
    {
        /// <summary>
        /// Converter that returns right Margin for Chart Range.
        /// </summary>
        /// <param name="values">
        /// 0, ChartContainer.ActualWidth. 
        /// 1, MaxValue. 
        /// 2, MinValue.
        /// 3, StartValue
        /// 4, SeparatorWidth
        /// 5, CurrentValue
        /// </param>
        /// <param name="targetType"></param>
        /// <param name="parameter"></param>
        /// <param name="culture"></param>
        /// <returns>Item Width</returns>
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var chartContainerWidth = ColumnChartHeper.ConvertToDobule(values[0]);
            var maxValue = ColumnChartHeper.ConvertToDobule(values[1]);
            var minValue = ColumnChartHeper.ConvertToDobule(values[2]);
            var startValue = ColumnChartHeper.ConvertToDobule(values[3]);
            var separatorWidth = ColumnChartHeper.ConvertToDobule(values[4]);
            var currentValue = ColumnChartHeper.ConvertToDobule(values[5]);

            if (chartContainerWidth > 0 && currentValue > 0 && maxValue > 0)
            {
                double averageUnitWidth = chartContainerWidth / (maxValue - minValue);
                var currentValueWidth = (currentValue - startValue) * averageUnitWidth - separatorWidth * 2;

                return currentValueWidth;
            }
            else
            {
                return null;
            }
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    /// <summary>
    /// Converter that returns Width for Result Series.
    /// </summary>
    public class TestResultChartResultSeriesWidthConverter : IMultiValueConverter
    {
        /// <summary>
        /// Converter that returns right Margin for Result Series.
        /// </summary>
        /// <param name="values">
        /// 0, ChartContainer.ActualWidth. 
        /// 1, MaxValue. 
        /// 2, MinValue.
        /// 3, RangeStartValue
        /// 4, RangeEndValue
        /// 5, SeparatorWidth
        /// 6, CurrentValue
        /// </param>
        /// <param name="targetType"></param>
        /// <param name="parameter"></param>
        /// <param name="culture"></param>
        /// <returns>Result Series Width</returns>
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var chartContainerWidth = ColumnChartHeper.ConvertToDobule(values[0]);
            var maxValue = ColumnChartHeper.ConvertToDobule(values[1]);
            var minValue = ColumnChartHeper.ConvertToDobule(values[2]);
            var rangeStartValue = ColumnChartHeper.ConvertToDobule(values[3]);
            var rangeEndValue = ColumnChartHeper.ConvertToDobule(values[4]);
            var separatorWidth = ColumnChartHeper.ConvertToDobule(values[5]);
            var currentValue = ColumnChartHeper.ConvertToDobule(values[6]);

            if (chartContainerWidth > 0 && currentValue > 0 && maxValue > 0)
            {
                double averageUnitWidth = chartContainerWidth / (maxValue - minValue);
                var currentValueWidth = (currentValue - minValue) * averageUnitWidth;

                if (currentValue > rangeStartValue)
                {
                    currentValueWidth += separatorWidth;
                }

                if (currentValue > rangeEndValue)
                {
                    currentValueWidth += separatorWidth;
                }

                return currentValueWidth;
            }
            else
            {
                return null;
            }
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public static class ColumnChartHeper
    {
        /// <summary>
        /// Trying to convert the provided value to double. If the conversion fails then -1 will be returned.
        /// </summary>
        /// <param name="value">The provided value needs to be covnerted to double.</param>
        /// <returns>Converted value will be returned. -1 will be return if failed.</returns>
        public static double ConvertToDobule(object value)
        {
            return value == DependencyProperty.UnsetValue ? -1 : System.Convert.ToDouble(value);
        }

        /// <summary>
        /// Trying to convert the provided value to int. If the conversion fails then -1 will be returned.
        /// </summary>
        /// <param name="value">The provided value needs to be covnerted to int.</param>
        /// <returns>Converted value will be returned. -1 will be return if failed.</returns>
        public static int ConvertToInt32(object value)
        {
            return value == DependencyProperty.UnsetValue ? -1 : System.Convert.ToInt32(value);
        }
    }
}
